﻿namespace BrowserCacheBustingTests
{
    using System;
    using System.Collections.Generic;
    using System.Configuration;
    using System.IO;
    using System.Linq;
    using BrowserCacheBustingUtilities;
    using NUnit.Framework;
    using System.Xml;

    [TestFixture]
    public class Tests
    {

        #region Members and constants

        private const string CacheBustingTestAssetsFilePath = @"c:\temp\BrowserCacheBusterTestDataOne.zip";
        private const string CacheBusterTestPath = @"c:\temp\BrowserCacheBusterTestDataOne\";
        private const string CacheBusterTestAssetsPath = @"c:\temp\BrowserCacheBusterTestDataOne\Assets\";
        private const string CacheBusterTestSourcePath = @"c:\temp\BrowserCacheBusterTestDataOne\Source\";
        private const string CacheBusterTestAlternativeSourcePath = @"c:\temp\BrowserCacheBusterTestDataOne\AnotherSourceFolder\";

        private const string CacheBusterBustingTestAssetsFilePath = @"c:\temp\BrowserCacheBusterTestDataTwo.zip";
        private const string CacheBusterBustingTestPath = @"c:\temp\BrowserCacheBusterTestDataTwo\";

        private const string CacheBusterBustingTestThreeAssetsFilePath = @"c:\temp\BrowserCacheBusterTestDataThree.zip";
        private const string CacheBusterBustingTestThreePath = @"c:\temp\BrowserCacheBusterTestDataThree\";

        private const string CacheBusterBustingTestFourAssetsFilePath = @"c:\temp\BrowserCacheBusterTestDataFour.zip";
        private const string CacheBusterBustingTestFourPath = @"c:\temp\BrowserCacheBusterTestDataFour\";

        private const string CacheBusterBustingTestFiveAssetsFilePath = @"c:\temp\BrowserCacheBusterTestDataFive.zip";
        private const string CacheBusterBustingTestFivePath = @"c:\temp\BrowserCacheBusterTestDataFive\";

        private const string CacheBusterBustingTestSixPath = @"c:\temp\BrowserCacheBusterTestDataSix\";
        private const string CacheBusterBustingTestSevenPath = @"c:\temp\BrowserCacheBusterTestDataSeven\";

        #endregion Members and constants

        #region Setup and tear down

        [SetUp]
        public void Setup()
        {
            // Reset app settings
            ConfigurationManager.AppSettings["Command"] = string.Empty;
            ConfigurationManager.AppSettings["CacheBustType"] = string.Empty;
            ConfigurationManager.AppSettings["AssetRootPath"] = string.Empty;
            ConfigurationManager.AppSettings["SourceRootPath"] = string.Empty;
            ConfigurationManager.AppSettings["AssetFolderPaths"] = string.Empty;
            ConfigurationManager.AppSettings["ExcludedAssetFolderPaths"] = string.Empty;
            ConfigurationManager.AppSettings["SourceFolderPaths"] = string.Empty;
            ConfigurationManager.AppSettings["ExcludedSourceFolderPaths"] = string.Empty;
            ConfigurationManager.AppSettings["AssetFolderNamesFilter"] = string.Empty;
            ConfigurationManager.AppSettings["AssetFolderNamesFilterType"] = string.Empty;
            ConfigurationManager.AppSettings["AssetFilePathsFilter"] = string.Empty;
            ConfigurationManager.AppSettings["AssetFilePathsFilterType"] = string.Empty;
            ConfigurationManager.AppSettings["AssetFileNamesFilter"] = string.Empty;
            ConfigurationManager.AppSettings["AssetFileNamesFilterType"] = string.Empty;
            ConfigurationManager.AppSettings["AssetFileExtensionsFilter"] = string.Empty;
            ConfigurationManager.AppSettings["AssetFileExtensionsFilterType"] = string.Empty;
            ConfigurationManager.AppSettings["SourceFolderNamesFilter"] = string.Empty;
            ConfigurationManager.AppSettings["SourceFolderNamesFilterType"] = string.Empty;
            ConfigurationManager.AppSettings["SourceFilePathsFilter"] = string.Empty;
            ConfigurationManager.AppSettings["SourceFilePathsFilterType"] = string.Empty;
            ConfigurationManager.AppSettings["SourceFileNamesFilter"] = string.Empty;
            ConfigurationManager.AppSettings["SourceFileNamesFilterType"] = string.Empty;
            ConfigurationManager.AppSettings["SourceFileExtensionsFilter"] = string.Empty;
            ConfigurationManager.AppSettings["SourceFileExtensionsFilterType"] = string.Empty;
            ConfigurationManager.AppSettings["DeleteOldFileVersions"] = string.Empty;
            ConfigurationManager.AppSettings["IncludedDomainNames"] = string.Empty;
            ConfigurationManager.AppSettings["OutputFilePath"] = string.Empty;
            ConfigurationManager.AppSettings["VersionFilePath"] = string.Empty;
            ConfigurationManager.AppSettings["MD5HashPrefix"] = "_MD5_";
            ConfigurationManager.AppSettings["NumberOfVersionsToKeep"] = string.Empty;

            CacheBuster.ResetArguments();
            CacheBuster.Output = new ConsoleOutput();
            CacheBuster.OutputExclusionsToConsole = true;

            CreateTestDirectory(CacheBusterTestPath);
            CreateTestDirectory(CacheBusterBustingTestPath);
            CreateTestDirectory(CacheBusterBustingTestThreePath);
            CreateTestDirectory(CacheBusterBustingTestFourPath);
            CreateTestDirectory(CacheBusterBustingTestFivePath);
            CreateTestDirectory(CacheBusterBustingTestSixPath); 
            CreateTestDirectory(CacheBusterBustingTestSevenPath);

            TestHelper.SaveResourceStreamToDisk("BrowserCacheBustingTests.TestData.BrowserCacheBusterTestDataOne.zip", CacheBustingTestAssetsFilePath);
            TestHelper.UnZipFile(CacheBustingTestAssetsFilePath);
            File.Delete(CacheBustingTestAssetsFilePath);

            TestHelper.SaveResourceStreamToDisk("BrowserCacheBustingTests.TestData.BrowserCacheBusterTestDataTwo.zip", CacheBusterBustingTestAssetsFilePath);
            TestHelper.UnZipFile(CacheBusterBustingTestAssetsFilePath);
            File.Delete(CacheBusterBustingTestAssetsFilePath);

            TestHelper.SaveResourceStreamToDisk("BrowserCacheBustingTests.TestData.BrowserCacheBusterTestDataThree.zip", CacheBusterBustingTestThreeAssetsFilePath);
            TestHelper.UnZipFile(CacheBusterBustingTestThreeAssetsFilePath);
            File.Delete(CacheBusterBustingTestThreeAssetsFilePath);

            TestHelper.SaveResourceStreamToDisk("BrowserCacheBustingTests.TestData.BrowserCacheBusterTestDataFour.zip", CacheBusterBustingTestFourAssetsFilePath);
            TestHelper.UnZipFile(CacheBusterBustingTestFourAssetsFilePath);
            File.Delete(CacheBusterBustingTestFourAssetsFilePath);

            TestHelper.SaveResourceStreamToDisk("BrowserCacheBustingTests.TestData.BrowserCacheBusterTestDataFive.zip", CacheBusterBustingTestFiveAssetsFilePath);
            TestHelper.UnZipFile(CacheBusterBustingTestFiveAssetsFilePath);
            File.Delete(CacheBusterBustingTestFiveAssetsFilePath);
        }

        [TearDown]
        public void TearDown()
        {
            Directory.Delete(CacheBusterTestPath, true);
            Directory.Delete(CacheBusterBustingTestPath, true);
            Directory.Delete(CacheBusterBustingTestThreePath, true);
            Directory.Delete(CacheBusterBustingTestFourPath, true);
            Directory.Delete(CacheBusterBustingTestFivePath, true);
            Directory.Delete(CacheBusterBustingTestSixPath, true);
            Directory.Delete(CacheBusterBustingTestSevenPath, true);
        }

        private void CreateTestDirectory(string path)
        {
            if (Directory.Exists(path))
                Directory.Delete(path, true);

            if (!Directory.Exists(path))
                Directory.CreateDirectory(path);
        }

        #endregion Setup and tear down

        #region Tests to validate command lines arguments

        [Test]
        public void VerifyArgumentsAreProcessedCorrectly()
        {
            string[] arguments = new[]
                                     {
                                         @"-arfp:c:\dev\web\assetroot\",
                                         @"-srfp:c:\dev\web\source\",
                                         @"-afp:c:\dev\web\assets\,c:\dev\web\assets2\",
                                         @"-afef:.dll,.exe,.swf,.mov",
                                         @"-afeft:1",
                                         @"-afonf:bin,obj",
                                         @"-afonft:1",
                                         @"-eafp:c:\dev\web\assets\temp\",
                                         @"-afpf:c:\dev\web\assets\temp\test.txt",
                                         @"-afpft:1",
                                         @"-afnf:test.txt,test2.txt",
                                         @"-afnft:1",
                                         @"-sfp:c:\dev\web\source\",
                                         @"-sfonf:obj,bin",
                                         @"-sfonft:1",
                                         @"-sfef:cs",
                                         @"-sfeft:1",
                                         @"-esfp:c:\dev\web\source\blah\",
                                         @"-sfpf:c:\dev\web\source\blah\test.txt",
                                         @"-sfpft:1",
                                         @"-sfnf:testing.text",
                                         @"-sfnft:1",
                                         @"-i:hostname.com",
                                         @"-d:1",
                                         @"-o:c:\temp\outputfilepath.txt",
                                         @"-v:c:\temp\versionfilepath.txt",
                                         @"-hp:_cheese_",
                                         @"-k:5"
                                     };

            CacheBuster.ProcessCommandLineArguments(arguments);
            Assert.AreEqual(@"c:\dev\web\assetroot\", CacheBuster.AssetRootPath);
            Assert.AreEqual(@"c:\dev\web\source\", CacheBuster.SourceRootPath);
            Assert.IsTrue(TestHelper.AreListsEqual(CacheBuster.AssetFolderPaths, new List<string> { @"c:\dev\web\assets\", @"c:\dev\web\assets2\" }));
            Assert.IsTrue(TestHelper.AreListsEqual(CacheBuster.AssetFolderNamesFilter, new List<string> { "bin", "obj" }));
            Assert.AreEqual(CacheBuster.AssetFolderNamesFilterType, CacheBuster.Filter.Include);
            Assert.IsTrue(TestHelper.AreListsEqual(CacheBuster.AssetFileExtensionsFilter, new List<string> { @".dll", @".exe", ".swf", ".mov" }));
            Assert.AreEqual(CacheBuster.AssetFileExtensionsFilterType, CacheBuster.Filter.Include);
            Assert.IsTrue(TestHelper.AreListsEqual(CacheBuster.ExcludedAssetFolderPaths, new List<string> { @"c:\dev\web\assets\temp\" }));
            Assert.IsTrue(TestHelper.AreListsEqual(CacheBuster.AssetFilePathsFilter, new List<string> { @"c:\dev\web\assets\temp\test.txt" }));
            Assert.AreEqual(CacheBuster.AssetFilePathsFilterType, CacheBuster.Filter.Include);
            Assert.IsTrue(TestHelper.AreListsEqual(CacheBuster.AssetFileNamesFilter, new List<string> { @"test.txt", @"test2.txt" }));
            Assert.AreEqual(CacheBuster.AssetFileNamesFilterType, CacheBuster.Filter.Include);
            Assert.IsTrue(TestHelper.AreListsEqual(CacheBuster.SourceFolderPaths, new List<string> { @"c:\dev\web\source\" }));
            Assert.IsTrue(TestHelper.AreListsEqual(CacheBuster.SourceFolderNamesFilter, new List<string> { "obj", "bin" }));
            Assert.AreEqual(CacheBuster.SourceFolderNamesFilterType, CacheBuster.Filter.Include);
            Assert.IsTrue(TestHelper.AreListsEqual(CacheBuster.SourceFileExtensionsFilter, new List<string> { @".cs" }));
            Assert.AreEqual(CacheBuster.SourceFileExtensionsFilterType, CacheBuster.Filter.Include);
            Assert.IsTrue(TestHelper.AreListsEqual(CacheBuster.ExcludedSourceFolderPaths, new List<string> { @"c:\dev\web\source\blah\" }));
            Assert.IsTrue(TestHelper.AreListsEqual(CacheBuster.SourceFilePathsFilter, new List<string> { @"c:\dev\web\source\blah\test.txt" }));
            Assert.AreEqual(CacheBuster.SourceFilePathsFilterType, CacheBuster.Filter.Include);
            Assert.IsTrue(TestHelper.AreListsEqual(CacheBuster.SourceFileNamesFilter, new List<string> { @"testing.text" }));
            Assert.AreEqual(CacheBuster.SourceFileNamesFilterType, CacheBuster.Filter.Include);
            Assert.IsTrue(TestHelper.AreListsEqual(CacheBuster.IncludedDomainNames, new List<string> { @"hostname.com" }));
            Assert.IsTrue(CacheBuster.DeleteOldFileVersions);
            Assert.AreEqual(@"c:\temp\outputfilepath.txt", CacheBuster.OutputFilePath);
            Assert.AreEqual(@"c:\temp\versionfilepath.txt", CacheBuster.VersionFilePath);
            Assert.AreEqual("_cheese_", CacheBuster.MD5HashPrefix);
            Assert.AreEqual(5, CacheBuster.NumberOfVersionsToKeep);
        }

        [Test]
        public void VerifyThatMultipleArgumentsAreProcessedCorrectlyWhenSentInAsOneArgumentString()
        {
            string[] arguments = new[] { @"-c:1 -arfp:c:\dev\web\assetroot\ -srfp:c:\dev\web\source\ -afp:c:\dev\web\assets\,c:\dev\web\assets2\ -afnf:test.txt,test2.txt -afnft:1 -afef:.dll,.exe,swf,mov -afeft:1 -eafp:c:\dev\web\assets\temp\ -afpf:c:\dev\web\assets\temp\test.txt -afpft:1 -sfp:c:\dev\web\source\ -sfef:.cs -sfeft:1 -esfp:c:\dev\web\source\blah\ -sfpft:1 -sfpf:c:\dev\web\source\blah\test.txt -sfpft:1 -sfnf:testing.text -sfnft:1 -i:hostname.com -o:c:\temp\outputfilepath.txt -afonf:bin,obj -afonft:1 -sfonf:obj,bin -sfonft:1 -v:c:\temp\versionfilepath.txt -hp:_cheese_ -k:2" };
            CacheBuster.ProcessCommandLineArguments(arguments);
            Assert.AreEqual(@"c:\dev\web\assetroot\", CacheBuster.AssetRootPath);
            Assert.AreEqual(@"c:\dev\web\source\", CacheBuster.SourceRootPath);
            Assert.IsTrue(TestHelper.AreListsEqual(CacheBuster.AssetFolderPaths, new List<string> { @"c:\dev\web\assets\", @"c:\dev\web\assets2\" }));
            Assert.IsTrue(TestHelper.AreListsEqual(CacheBuster.AssetFolderNamesFilter, new List<string> { "bin", "obj" }));
            Assert.AreEqual(CacheBuster.AssetFolderNamesFilterType, CacheBuster.Filter.Include);
            Assert.IsTrue(TestHelper.AreListsEqual(CacheBuster.AssetFileExtensionsFilter, new List<string> { @".dll", @".exe", ".swf", ".mov" }));
            Assert.AreEqual(CacheBuster.AssetFileExtensionsFilterType, CacheBuster.Filter.Include);
            Assert.IsTrue(TestHelper.AreListsEqual(CacheBuster.ExcludedAssetFolderPaths, new List<string> { @"c:\dev\web\assets\temp\" }));
            Assert.IsTrue(TestHelper.AreListsEqual(CacheBuster.AssetFilePathsFilter, new List<string> { @"c:\dev\web\assets\temp\test.txt" }));
            Assert.AreEqual(CacheBuster.AssetFilePathsFilterType, CacheBuster.Filter.Include);
            Assert.IsTrue(TestHelper.AreListsEqual(CacheBuster.AssetFileNamesFilter, new List<string> { @"test.txt", @"test2.txt" }));
            Assert.AreEqual(CacheBuster.AssetFileNamesFilterType, CacheBuster.Filter.Include);
            Assert.IsTrue(TestHelper.AreListsEqual(CacheBuster.SourceFolderPaths, new List<string> { @"c:\dev\web\source\" }));
            Assert.IsTrue(TestHelper.AreListsEqual(CacheBuster.SourceFolderNamesFilter, new List<string> { "obj", "bin" }));
            Assert.AreEqual(CacheBuster.SourceFolderNamesFilterType, CacheBuster.Filter.Include);
            Assert.IsTrue(TestHelper.AreListsEqual(CacheBuster.SourceFileExtensionsFilter, new List<string> { @".cs" }));
            Assert.AreEqual(CacheBuster.SourceFileExtensionsFilterType, CacheBuster.Filter.Include);
            Assert.IsTrue(TestHelper.AreListsEqual(CacheBuster.ExcludedSourceFolderPaths, new List<string> { @"c:\dev\web\source\blah\" }));
            Assert.IsTrue(TestHelper.AreListsEqual(CacheBuster.SourceFilePathsFilter, new List<string> { @"c:\dev\web\source\blah\test.txt" }));
            Assert.AreEqual(CacheBuster.SourceFilePathsFilterType, CacheBuster.Filter.Include);
            Assert.IsTrue(TestHelper.AreListsEqual(CacheBuster.SourceFileNamesFilter, new List<string> { @"testing.text" }));
            Assert.AreEqual(CacheBuster.SourceFileNamesFilterType, CacheBuster.Filter.Include);
            Assert.IsTrue(TestHelper.AreListsEqual(CacheBuster.IncludedDomainNames, new List<string> { @"hostname.com" }));
            Assert.AreEqual(CacheBuster.CommandType.GetUniqueFileExtensions, CacheBuster.Command);
            Assert.IsFalse(CacheBuster.DeleteOldFileVersions);
            Assert.AreEqual(@"c:\temp\outputfilepath.txt", CacheBuster.OutputFilePath);
            Assert.AreEqual(@"c:\temp\versionfilepath.txt", CacheBuster.VersionFilePath);
            Assert.AreEqual("_cheese_", CacheBuster.MD5HashPrefix);
            Assert.AreEqual(2, CacheBuster.NumberOfVersionsToKeep);
        }

        [Test]
        public void VerifyThatErrorsAreReportedWhenRequiredArgumentsAreNotSpecified()
        {
            string[] arguments = new string[] { };
            List<string> errors = CacheBuster.ProcessCommandLineArguments(arguments);
            Assert.AreEqual(3, errors.Count);
            Assert.IsTrue(errors[0].Contains("-srfp"));
            Assert.IsTrue(errors[1].Contains("-afp"));
            Assert.IsTrue(errors[2].Contains("-sfp"));

            arguments = new[] { @"-afp:" + CacheBusterTestAssetsPath };
            errors = CacheBuster.ProcessCommandLineArguments(arguments);
            Assert.AreEqual(2, errors.Count);
            Assert.IsTrue(errors[0].Contains("-srfp"));
            Assert.IsTrue(errors[1].Contains("-sfp"));

            arguments = new[] { @"-afp:" + CacheBusterTestAssetsPath };
            errors = CacheBuster.ProcessCommandLineArguments(arguments);
            Assert.AreEqual(2, errors.Count);
            Assert.IsTrue(errors[0].Contains("-srfp"));
            Assert.IsTrue(errors[1].Contains("-sfp"));
        }

        [Test]
        public void VerifyThatArgumentsAreLoadingCorrectlyFromAppSettings()
        {
            ConfigurationManager.AppSettings["Command"] = "2";
            ConfigurationManager.AppSettings["AssetRootPath"] = @"c:\dev\web\assetroot\";
            ConfigurationManager.AppSettings["SourceRootPath"] = @"c:\dev\web\sourcerootpath\";
            ConfigurationManager.AppSettings["AssetFolderPaths"] = @"c:\dev\web\assets\,c:\dev\web\assets2\";
            ConfigurationManager.AppSettings["AssetFolderNamesFilter"] = "bin,obj";
            ConfigurationManager.AppSettings["AssetFolderNamesFilterType"] = "1";
            ConfigurationManager.AppSettings["AssetFileExtensionsFilterType"] = "1";
            ConfigurationManager.AppSettings["AssetFileExtensionsFilter"] = @".dll,.exe,.swf,mov";
            ConfigurationManager.AppSettings["AssetFileExtensionsFilterType"] = "1";
            ConfigurationManager.AppSettings["ExcludedAssetFolderPaths"] = @"c:\dev\web\assets\temp\";
            ConfigurationManager.AppSettings["AssetFilePathsFilter"] = @"c:\dev\web\assets\temp\test.txt";
            ConfigurationManager.AppSettings["AssetFilePathsFilterType"] = "1";
            ConfigurationManager.AppSettings["AssetFileNamesFilter"] = @"test.txt,test2.txt";
            ConfigurationManager.AppSettings["AssetFileNamesFilterType"] = "1";
            ConfigurationManager.AppSettings["SourceFolderPaths"] = @"c:\dev\web\source\";
            ConfigurationManager.AppSettings["SourceFolderNamesFilter"] = "obj,bin";
            ConfigurationManager.AppSettings["SourceFolderNamesFilterType"] = "1";
            ConfigurationManager.AppSettings["SourceFileExtensionsFilter"] = @".cs";
            ConfigurationManager.AppSettings["SourceFileExtensionsFilterType"] = "1";
            ConfigurationManager.AppSettings["ExcludedSourceFolderPaths"] = @"c:\dev\web\source\blah\";
            ConfigurationManager.AppSettings["SourceFilePathsFilter"] = @"c:\dev\web\source\blah\test.txt";
            ConfigurationManager.AppSettings["SourceFilePathsFilterType"] = "1";
            ConfigurationManager.AppSettings["SourceFileNamesFilter"] = @"testing.text";
            ConfigurationManager.AppSettings["SourceFileNamesFilterType"] = "1";
            ConfigurationManager.AppSettings["DeleteOldFileVersions"] = @"1";
            ConfigurationManager.AppSettings["IncludedDomainNames"] = @"hostname.com";
            ConfigurationManager.AppSettings["OutputFilePath"] = @"c:\temp\outputfilepath.txt";
            ConfigurationManager.AppSettings["VersionFilePath"] = @"c:\temp\versionfilepath.txt";
            ConfigurationManager.AppSettings["MD5HashPrefix"] = @"_cheese_";
            ConfigurationManager.AppSettings["NumberOfVersionsToKeep"] = "7";

            CacheBuster.ResetArguments();

            Assert.AreEqual(@"c:\dev\web\assetroot\", CacheBuster.AssetRootPath);
            Assert.AreEqual(@"c:\dev\web\sourcerootpath\", CacheBuster.SourceRootPath);
            Assert.IsTrue(TestHelper.AreListsEqual(CacheBuster.AssetFolderPaths, new List<string> { @"c:\dev\web\assets\", @"c:\dev\web\assets2\" }));
            Assert.IsTrue(TestHelper.AreListsEqual(CacheBuster.AssetFileExtensionsFilter, new List<string> { @".dll", @".exe", ".swf", ".mov" }));
            Assert.AreEqual(CacheBuster.AssetFileExtensionsFilterType, CacheBuster.Filter.Include);

            Assert.IsTrue(TestHelper.AreListsEqual(CacheBuster.ExcludedAssetFolderPaths, new List<string> { @"c:\dev\web\assets\temp\" }));

            Assert.IsTrue(TestHelper.AreListsEqual(CacheBuster.AssetFolderNamesFilter, new List<string> { "bin", "obj" }));
            Assert.AreEqual(CacheBuster.AssetFolderNamesFilterType, CacheBuster.Filter.Include);

            Assert.IsTrue(TestHelper.AreListsEqual(CacheBuster.AssetFilePathsFilter, new List<string> { @"c:\dev\web\assets\temp\test.txt" }));
            Assert.AreEqual(CacheBuster.AssetFilePathsFilterType, CacheBuster.Filter.Include);

            Assert.IsTrue(TestHelper.AreListsEqual(CacheBuster.AssetFileNamesFilter, new List<string> { @"test.txt", @"test2.txt" }));
            Assert.AreEqual(CacheBuster.AssetFileNamesFilterType, CacheBuster.Filter.Include);

            Assert.IsTrue(TestHelper.AreListsEqual(CacheBuster.SourceFolderPaths, new List<string> { @"c:\dev\web\source\" }));
            Assert.IsTrue(TestHelper.AreListsEqual(CacheBuster.SourceFileExtensionsFilter, new List<string> { @".cs" }));
            Assert.AreEqual(CacheBuster.SourceFileExtensionsFilterType, CacheBuster.Filter.Include);

            Assert.IsTrue(TestHelper.AreListsEqual(CacheBuster.ExcludedSourceFolderPaths, new List<string> { @"c:\dev\web\source\blah\" }));

            Assert.IsTrue(TestHelper.AreListsEqual(CacheBuster.SourceFolderNamesFilter, new List<string> { "obj", "bin" }));
            Assert.AreEqual(CacheBuster.SourceFolderNamesFilterType, CacheBuster.Filter.Include);

            Assert.IsTrue(TestHelper.AreListsEqual(CacheBuster.SourceFilePathsFilter, new List<string> { @"c:\dev\web\source\blah\test.txt" }));
            Assert.AreEqual(CacheBuster.SourceFilePathsFilterType, CacheBuster.Filter.Include);

            Assert.IsTrue(TestHelper.AreListsEqual(CacheBuster.SourceFileNamesFilter, new List<string> { @"testing.text" }));
            Assert.AreEqual(CacheBuster.SourceFileNamesFilterType, CacheBuster.Filter.Include);

            Assert.IsTrue(TestHelper.AreListsEqual(CacheBuster.IncludedDomainNames, new List<string> { @"hostname.com" }));
            Assert.IsTrue(CacheBuster.DeleteOldFileVersions);
            Assert.AreEqual(@"c:\temp\outputfilepath.txt", CacheBuster.OutputFilePath);
            Assert.AreEqual(@"c:\temp\versionfilepath.txt", CacheBuster.VersionFilePath);
            Assert.AreEqual("_cheese_", CacheBuster.MD5HashPrefix);
            Assert.AreEqual(7, CacheBuster.NumberOfVersionsToKeep);
        }

        [Test]
        public void VerifyThatErrorsAreReportedWhenInvalidFilePathsAreUsed()
        {
            string[] arguments = new[] { "-afp:" + CacheBusterTestAssetsPath + @"Folder1\", "-sfp:" + CacheBusterTestAssetsPath };
            List<string> errors = CacheBuster.ProcessCommandLineArguments(arguments);

            Assert.AreEqual(2, errors.Count);
            Assert.AreEqual("You must specify a source root path using the -srfp: argument.", errors[0]);
            Assert.IsTrue(errors[1].Contains("-afp") && errors[1].Contains("'" + CacheBusterTestAssetsPath + @"Folder1\" + "'"));

            arguments = new[] { "-eafp:" + CacheBusterTestAssetsPath + @"Folder1\", "-afp:" + CacheBusterTestAssetsPath, "-sfp:" + CacheBusterTestAssetsPath, "-srfp:" + CacheBusterTestAssetsPath };
            errors = CacheBuster.ProcessCommandLineArguments(arguments);
            Assert.AreEqual(1, errors.Count);
            Assert.IsTrue(errors[0].Contains("-eafp") && errors[0].Contains("'" + CacheBusterTestAssetsPath + @"Folder1\" + "'"));

            arguments = new[] { "-esfp:" + CacheBusterTestAssetsPath + @"Folder1\", "-afp:" + CacheBusterTestAssetsPath, "-sfp:" + CacheBusterTestAssetsPath, "-srfp:" + CacheBusterTestAssetsPath };
            errors = CacheBuster.ProcessCommandLineArguments(arguments);
            Assert.AreEqual(1, errors.Count);
            Assert.IsTrue(errors[0].Contains("-esfp") && errors[0].Contains("'" + CacheBusterTestAssetsPath + @"Folder1\" + "'"));

            arguments = new[] { "-afp:" + CacheBusterTestAssetsPath, "-sfp:" + CacheBusterTestAssetsPath + @"Folder1\", "-srfp:" + CacheBusterTestAssetsPath };
            errors = CacheBuster.ProcessCommandLineArguments(arguments);
            Assert.AreEqual(1, errors.Count);
            Assert.IsTrue(errors[0].Contains("-sfp") && errors[0].Contains("'" + CacheBusterTestAssetsPath + @"Folder1\" + "'"));

            arguments = new[] { "-afp:" + CacheBusterTestAssetsPath, "-sfp:" + CacheBusterTestAssetsPath + @"Folder1\", "-srfp:" + CacheBusterTestAssetsPath + "Cheese\\" };
            errors = CacheBuster.ProcessCommandLineArguments(arguments);
            Assert.AreEqual(2, errors.Count);
            Assert.IsTrue(errors[0].Contains("-srfp") && errors[0].Contains("'" + CacheBusterTestAssetsPath + @"Cheese\" + "'"));
            Assert.IsTrue(errors[1].Contains("-sfp") && errors[1].Contains("'" + CacheBusterTestAssetsPath + @"Folder1\" + "'"));

            arguments = new[] { "-afp:" + CacheBusterTestAssetsPath, "-sfp:" + CacheBusterTestAssetsPath, "-srfp:" + CacheBusterTestAssetsPath, "-arfp:" + CacheBusterTestAssetsPath + "Cheese\\" };
            errors = CacheBuster.ProcessCommandLineArguments(arguments);
            Assert.AreEqual(1, errors.Count);
            Assert.IsTrue(errors[0].Contains("-arfp") && errors[0].Contains("'" + CacheBusterTestAssetsPath + @"Cheese\" + "'"));

            arguments = new[] { "-afp:" + CacheBusterTestAssetsPath, "-sfp:" + CacheBusterTestAssetsPath, "-srfp:" + CacheBusterTestAssetsPath, @"-o:c:\abczs872384787iajsdfljlkajs\" };
            errors = CacheBuster.ProcessCommandLineArguments(arguments);
            Assert.AreEqual(1, errors.Count);
            Assert.IsTrue(errors[0].Contains("-o") && errors[0].Contains("'" + @"c:\abczs872384787iajsdfljlkajs\" + "'"));

            arguments = new[] { "-m:1", "-afp:" + CacheBusterTestAssetsPath, "-sfp:" + CacheBusterTestAssetsPath, "-srfp:" + CacheBusterTestAssetsPath };
            errors = CacheBuster.ProcessCommandLineArguments(arguments);
            Assert.AreEqual(1, errors.Count);
            Assert.IsTrue(errors[0].Contains("-v"));

            arguments = new[] { "-m:1", "-afp:" + CacheBusterTestAssetsPath, "-sfp:" + CacheBusterTestAssetsPath, "-srfp:" + CacheBusterTestAssetsPath, @"-v:c:\abczs872384787iajsdfljlkajs\" };
            errors = CacheBuster.ProcessCommandLineArguments(arguments);
            Assert.AreEqual(1, errors.Count);
            Assert.IsTrue(errors[0].Contains("-v") && errors[0].Contains("'" + @"c:\abczs872384787iajsdfljlkajs\" + "'"));

        }

        [Test]
        public void VerifyThatAssetRootPathAndSourceRootPathPlaceHoldersAreUpdatedCorrectlyWhenDefinedInArguments()
        {
            string[] arguments = new[]
                                     {
                                         @"-arfp:c:\dev\web\asset",
                                         @"-srfp:c:\dev\web\source\",
                                         @"-afp:%AssetRootPath%\test\,%AssetRootPath%test2",
                                         @"-eafp:%AssetRootPath%\temp\",
                                         @"-afpf:%AssetRootPath%\temp\test.txt",
                                         @"-sfp:%SourceRootPath%\test",
                                         @"-esfp:%SourceRootPath%blah\",
                                         @"-sfpf:%SourceRootPath%\blah\test.txt"
                                     };

            CacheBuster.ProcessCommandLineArguments(arguments);
            Assert.AreEqual(@"c:\dev\web\asset\", CacheBuster.AssetRootPath);
            Assert.AreEqual(@"c:\dev\web\source\", CacheBuster.SourceRootPath);

            Assert.IsTrue(TestHelper.AreListsEqual(CacheBuster.AssetFolderPaths, new List<string> { @"c:\dev\web\asset\test\", @"c:\dev\web\asset\test2\" }));
            Assert.IsTrue(TestHelper.AreListsEqual(CacheBuster.ExcludedAssetFolderPaths, new List<string> { @"c:\dev\web\asset\temp\" }));
            Assert.IsTrue(TestHelper.AreListsEqual(CacheBuster.AssetFilePathsFilter, new List<string> { @"c:\dev\web\asset\temp\test.txt" }));
            Assert.IsTrue(TestHelper.AreListsEqual(CacheBuster.SourceFolderPaths, new List<string> { @"c:\dev\web\source\test\" }));
            Assert.IsTrue(TestHelper.AreListsEqual(CacheBuster.ExcludedSourceFolderPaths, new List<string> { @"c:\dev\web\source\blah\" }));
            Assert.IsTrue(TestHelper.AreListsEqual(CacheBuster.SourceFilePathsFilter, new List<string> { @"c:\dev\web\source\blah\test.txt" }));
        }

        [Test]
        public void VerifyThatWhenFolderPathsAreProcessedTrailingSlashesAreAddedToThePath()
        {
            string[] arguments = new[]
                                     {
                                         @"-arfp:c:\dev\web\asset",
                                         @"-srfp:c:\dev\web\source",
                                         @"-afp:c:\dev\web\asset\test,c:\dev\web\asset\test2",
                                         @"-eafp:c:\dev\web\asset\temp",
                                         @"-sfp:c:\dev\web\source\test",
                                         @"-esfp:c:\dev\web\source\blah"
                                     };

            CacheBuster.ProcessCommandLineArguments(arguments);
            Assert.AreEqual(@"c:\dev\web\asset\", CacheBuster.AssetRootPath);
            Assert.AreEqual(@"c:\dev\web\source\", CacheBuster.SourceRootPath);
            Assert.IsTrue(TestHelper.AreListsEqual(CacheBuster.AssetFolderPaths, new List<string> { @"c:\dev\web\asset\test\", @"c:\dev\web\asset\test2\" }));
            Assert.IsTrue(TestHelper.AreListsEqual(CacheBuster.ExcludedAssetFolderPaths, new List<string> { @"c:\dev\web\asset\temp\" }));
            Assert.IsTrue(TestHelper.AreListsEqual(CacheBuster.SourceFolderPaths, new List<string> { @"c:\dev\web\source\test\" }));
            Assert.IsTrue(TestHelper.AreListsEqual(CacheBuster.ExcludedSourceFolderPaths, new List<string> { @"c:\dev\web\source\blah\" }));
        }

        [Test]
        public void VerifyThatDotDotPathsAreProcessedCorrectly()
        {
            string[] arguments = new[]
                                     {
                                         @"-arfp:..\folderone",
                                         @"-srfp:..\..\foldertwo",
                                         @"-afp:..\..\..\folderthree",
                                         @"-eafp:..\folderfour",
                                         @"-sfp:..\folderfive",
                                         @"-esfp:..\..\foldersix",
                                         @"-afpf:..\..\fileone.txt",
                                         @"-sfpf:..\filetwo.txt"
                                     };

            CacheBuster.ApplicationPath = new DirectoryInfo(@"c:\one\two\three\four");
            CacheBuster.ProcessCommandLineArguments(arguments);
            Assert.AreEqual(@"c:\one\two\three\folderone\", CacheBuster.AssetRootPath);
            Assert.AreEqual(@"c:\one\two\foldertwo\", CacheBuster.SourceRootPath);
            Assert.IsTrue(TestHelper.AreListsEqual(CacheBuster.AssetFolderPaths, new List<string> { @"c:\one\folderthree\" }));
            Assert.IsTrue(TestHelper.AreListsEqual(CacheBuster.ExcludedAssetFolderPaths, new List<string> { @"c:\one\two\three\folderfour\" }));
            Assert.IsTrue(TestHelper.AreListsEqual(CacheBuster.SourceFolderPaths, new List<string> { @"c:\one\two\three\folderfive\" }));
            Assert.IsTrue(TestHelper.AreListsEqual(CacheBuster.ExcludedSourceFolderPaths, new List<string> { @"c:\one\two\foldersix\" }));
            Assert.IsTrue(TestHelper.AreListsEqual(CacheBuster.AssetFilePathsFilter, new List<string> { @"c:\one\two\fileone.txt" }));
            Assert.IsTrue(TestHelper.AreListsEqual(CacheBuster.SourceFilePathsFilter, new List<string> { @"c:\one\two\three\filetwo.txt" }));
        }

        [Test]
        public void VerifyThatDotPathsAreProcessedCorrectly()
        {
            string[] arguments = new[]
                                     {
                                         @"-arfp:.\folderone",
                                         @"-srfp:.\.\foldertwo",
                                         @"-afp:.\.\.\folderthree",
                                         @"-eafp:.\folderfour",
                                         @"-sfp:.\folderfive",
                                         @"-esfp:.\.\foldersix",
                                         @"-afpf:.\.\fileone.txt",
                                         @"-sfpf:.\filetwo.txt"
                                     };

            CacheBuster.ApplicationPath = new DirectoryInfo(@"c:\one\two\three\four");
            CacheBuster.ProcessCommandLineArguments(arguments);
            Assert.AreEqual(@"c:\one\two\three\four\folderone\", CacheBuster.AssetRootPath);
            Assert.AreEqual(@"c:\one\two\three\four\foldertwo\", CacheBuster.SourceRootPath);
            Assert.IsTrue(TestHelper.AreListsEqual(CacheBuster.AssetFolderPaths, new List<string> { @"c:\one\two\three\four\folderthree\" }));
            Assert.IsTrue(TestHelper.AreListsEqual(CacheBuster.ExcludedAssetFolderPaths, new List<string> { @"c:\one\two\three\four\folderfour\" }));
            Assert.IsTrue(TestHelper.AreListsEqual(CacheBuster.SourceFolderPaths, new List<string> { @"c:\one\two\three\four\folderfive\" }));
            Assert.IsTrue(TestHelper.AreListsEqual(CacheBuster.ExcludedSourceFolderPaths, new List<string> { @"c:\one\two\three\four\foldersix\" }));
            Assert.IsTrue(TestHelper.AreListsEqual(CacheBuster.AssetFilePathsFilter, new List<string> { @"c:\one\two\three\four\fileone.txt" }));
            Assert.IsTrue(TestHelper.AreListsEqual(CacheBuster.SourceFilePathsFilter, new List<string> { @"c:\one\two\three\four\filetwo.txt" }));
        }

        [Test]
        public void VerifyThatDotDotPathsAreProcessedCorrectlyFromAppSettings()
        {
            ConfigurationManager.AppSettings["AssetRootPath"] = @"..\folderone";
            ConfigurationManager.AppSettings["SourceRootPath"] = @"..\..\foldertwo";
            ConfigurationManager.AppSettings["AssetFolderPaths"] = @"..\..\..\folderthree";
            ConfigurationManager.AppSettings["ExcludedAssetFolderPaths"] = @"..\folderfour";
            ConfigurationManager.AppSettings["AssetFilePathsFilter"] = @"..\..\fileone.txt";
            ConfigurationManager.AppSettings["SourceFolderPaths"] = @"..\folderfive";
            ConfigurationManager.AppSettings["ExcludedSourceFolderPaths"] = @"..\..\foldersix";
            ConfigurationManager.AppSettings["SourceFilePathsFilter"] = @"..\filetwo.txt";

            CacheBuster.ApplicationPath = new DirectoryInfo(@"c:\one\two\three\four");
            CacheBuster.ResetArguments();
            
            Assert.AreEqual(@"c:\one\two\three\folderone\", CacheBuster.AssetRootPath);
            Assert.AreEqual(@"c:\one\two\foldertwo\", CacheBuster.SourceRootPath);
            Assert.IsTrue(TestHelper.AreListsEqual(CacheBuster.AssetFolderPaths, new List<string> { @"c:\one\folderthree\" }));
            Assert.IsTrue(TestHelper.AreListsEqual(CacheBuster.ExcludedAssetFolderPaths, new List<string> { @"c:\one\two\three\folderfour\" }));
            Assert.IsTrue(TestHelper.AreListsEqual(CacheBuster.SourceFolderPaths, new List<string> { @"c:\one\two\three\folderfive\" }));
            Assert.IsTrue(TestHelper.AreListsEqual(CacheBuster.ExcludedSourceFolderPaths, new List<string> { @"c:\one\two\foldersix\" }));
            Assert.IsTrue(TestHelper.AreListsEqual(CacheBuster.AssetFilePathsFilter, new List<string> { @"c:\one\two\fileone.txt" }));
            Assert.IsTrue(TestHelper.AreListsEqual(CacheBuster.SourceFilePathsFilter, new List<string> { @"c:\one\two\three\filetwo.txt" }));
        }

        #endregion Tests to validate command lines arguments

        #region CacheBuster Tests

        [Test]
        public void TestGetUniqueFileExtensions()
        {
            string[] arguments = new[]
                                     {
                                         @"-srfp:" + CacheBusterTestPath,
                                         @"-afp:" + CacheBusterTestAssetsPath,
                                         @"-sfp:" + CacheBusterTestSourcePath + "," + CacheBusterTestAlternativeSourcePath,
                                         "-c:1"
                                     };

            CacheBuster.Output = new StringBuilderOutput();
            CacheBuster.ProcessCommandLineArguments(arguments);
            CacheBuster.Go();

            string output = CacheBuster.Output.Data.ToString();

            const string toSearchFor = "Source folders unique extensions:";
            string assetsString = output.Substring(0, output.IndexOf(toSearchFor));
            assetsString = assetsString.Substring(assetsString.IndexOf(":") + 1);
            string sourceString = output.Substring(output.IndexOf(toSearchFor) + toSearchFor.Length);

            List<string> assetsExtensions = assetsString.Split('\r', '\n').Where(c => !string.IsNullOrWhiteSpace(c)).ToList();
            List<string> sourceExtensions = sourceString.Split('\r', '\n').Where(c => !string.IsNullOrWhiteSpace(c)).ToList();

            // assert
            Assert.AreEqual(4, assetsExtensions.Count);
            Assert.IsTrue(assetsExtensions.Any(c => string.Equals(c, ".css : 4")));
            Assert.IsTrue(assetsExtensions.Any(c => string.Equals(c, ".txt : 3")));
            Assert.IsTrue(assetsExtensions.Any(c => string.Equals(c, ".png : 2")));
            Assert.IsTrue(assetsExtensions.Any(c => string.Equals(c, ".jpg : 1")));


            Assert.AreEqual(3, sourceExtensions.Count);
            Assert.IsTrue(sourceExtensions.Any(c => string.Equals(c, ".aspx : 6")));
            Assert.IsTrue(sourceExtensions.Any(c => string.Equals(c, ".ascx : 1")));
            Assert.IsTrue(sourceExtensions.Any(c => string.Equals(c, ".dll : 1")));
        }

        [Test]
        public void TestGetUniqueFileExtensionsWithExcludedFoldersFilesAndExtensions()
        {
            string[] arguments = new[]
                                     {
                                         @"-srfp:" + CacheBusterTestPath,
                                         "-afp:" + CacheBusterTestAssetsPath,
                                         "-sfp:" + CacheBusterTestSourcePath + "," + CacheBusterTestAlternativeSourcePath,
                                         "-c:1",
                                         "-sfonf:bin,obj",
                                         "-sfonft:0",
                                         "-afef:.jpg",
                                         "-eafp:" + CacheBusterTestAssetsPath + @"Styles\Specific\",
                                         "-afpf:" + CacheBusterTestAssetsPath + @"Styles\ie6.css",
                                         "-afnf:ie8.css",
                                         "-sfef:.ascx",
                                         "-esfp:" + CacheBusterTestAlternativeSourcePath + "AdminTools",
                                         "-sfpf:" + CacheBusterTestAlternativeSourcePath + @"Default.aspx",
                                         "-sfnf:Sitemap.aspx"
                                     };

            CacheBuster.Output = new StringBuilderOutput();
            CacheBuster.OutputExclusionsToConsole = false;
            CacheBuster.ProcessCommandLineArguments(arguments);
            CacheBuster.Go();

            string output = CacheBuster.Output.Data.ToString();
            List<string> assetsExtensions = GetAssetExtensions(output);
            List<string> sourceExtensions = GetSourceExtensions(output);

            Assert.AreEqual(3, assetsExtensions.Count);
            Assert.IsTrue(assetsExtensions.Any(c => string.Equals(c, ".css : 1")));
            Assert.IsTrue(assetsExtensions.Any(c => string.Equals(c, ".txt : 3")));
            Assert.IsTrue(assetsExtensions.Any(c => string.Equals(c, ".png : 2")));
            Assert.IsFalse(assetsExtensions.Any(c => string.Equals(c, ".jpg : 1")));

            Assert.AreEqual(1, sourceExtensions.Count);
            Assert.IsTrue(sourceExtensions.Any(c => string.Equals(c, ".aspx : 1")));
            Assert.IsFalse(sourceExtensions.Any(c => string.Equals(c, ".ascx : 1")));
        }

        [Test]
        public void TestGetUniqueFileExtensionsWithIncludedFoldersFilesAndExtensions()
        {
            string[] arguments = new[]
                                     {
                                         @"-srfp:" + CacheBusterTestPath,
                                         "-afp:" + CacheBusterTestAssetsPath,
                                         "-sfp:" + CacheBusterTestSourcePath + "," + CacheBusterTestAlternativeSourcePath,
                                         "-c:1",
                                         "-afef:.css",
                                         "-afeft:1",
                                         "-eafp:" + CacheBusterTestAssetsPath + @"Styles\Specific\",
                                         "-afpf:" + CacheBusterTestAssetsPath + @"Styles\ie6.css",
                                         "-afpft:1",
                                         "-afnf:ie6.css",
                                         "-afnft:1",
                                         "-sfef:.ascx",
                                         "-sfeft:1",
                                         "-sfpf:" + CacheBusterTestSourcePath + @"Controls\Control.ascx",
                                         "-sfpft:1",
                                         "-sfnf:Control.ascx",
                                         "-sfnft:1"
                                     };

            CacheBuster.Output = new StringBuilderOutput();
            CacheBuster.OutputExclusionsToConsole = false;
            CacheBuster.ProcessCommandLineArguments(arguments);
            
            CacheBuster.Go();

            string output = CacheBuster.Output.Data.ToString();
            List<string> assetsExtensions = GetAssetExtensions(output);
            List<string> sourceExtensions = GetSourceExtensions(output);

            Assert.AreEqual(1, assetsExtensions.Count);
            Assert.IsTrue(assetsExtensions.Any(c => string.Equals(c, ".css : 1")));

            Assert.AreEqual(1, sourceExtensions.Count);
            Assert.IsTrue(sourceExtensions.Any(c => string.Equals(c, ".ascx : 1")));
        }

        [Test]
        public void TestGetUniqueFileExtensionsWithIncludedFolderNames()
        {
            string[] arguments = new[]
                                     {
                                         @"-srfp:" + CacheBusterTestPath,
                                         "-afp:" + CacheBusterTestAssetsPath,
                                         "-sfp:" + CacheBusterTestSourcePath + "," + CacheBusterTestAlternativeSourcePath,
                                         "-c:1",
                                         "-afonf:specific,images",
                                         "-afonft:1",
                                         "-sfonf:obj,pages",
                                         "-sfonft:1",
                                     };

            CacheBuster.Output = new StringBuilderOutput();
            CacheBuster.OutputExclusionsToConsole = false;
            CacheBuster.ProcessCommandLineArguments(arguments);
            CacheBuster.Go();

            string output = CacheBuster.Output.Data.ToString();
            List<string> assetsExtensions = GetAssetExtensions(output);
            List<string> sourceExtensions = GetSourceExtensions(output);

            Assert.AreEqual(3, assetsExtensions.Count);
            Assert.IsTrue(assetsExtensions.Any(c => string.Equals(c, ".css : 1")));
            Assert.IsTrue(assetsExtensions.Any(c => string.Equals(c, ".png : 2")));
            Assert.IsTrue(assetsExtensions.Any(c => string.Equals(c, ".jpg : 1")));

            Assert.AreEqual(2, sourceExtensions.Count);
            Assert.IsTrue(sourceExtensions.Any(c => string.Equals(c, ".aspx : 1")));
            Assert.IsTrue(sourceExtensions.Any(c => string.Equals(c, ".dll : 1")));
        }

        [Test]
        public void TestGetUniqueFileExtensionsWithExcludedFolderNames()
        {
            string[] arguments = new[]
                                     {
                                         @"-srfp:" + CacheBusterTestPath,
                                         "-afp:" + CacheBusterTestAssetsPath,
                                         "-sfp:" + CacheBusterTestSourcePath,
                                         "-c:1",
                                         "-afonf:specific,images",
                                         "-afonft:0",
                                         "-sfonf:obj,pages",
                                         "-sfonft:0",
                                     };

            CacheBuster.Output = new StringBuilderOutput();
            CacheBuster.OutputExclusionsToConsole = false;
            CacheBuster.ProcessCommandLineArguments(arguments);
            CacheBuster.Go();

            string output = CacheBuster.Output.Data.ToString();
            List<string> assetsExtensions = GetAssetExtensions(output);
            List<string> sourceExtensions = GetSourceExtensions(output);

            Assert.AreEqual(2, assetsExtensions.Count);
            Assert.IsTrue(assetsExtensions.Any(c => string.Equals(c, ".css : 3")));
            Assert.IsTrue(assetsExtensions.Any(c => string.Equals(c, ".txt : 3")));

            Assert.AreEqual(1, sourceExtensions.Count);
            Assert.IsTrue(sourceExtensions.Any(c => string.Equals(c, ".ascx : 1")));
        }

        [Test]
        public void WhenApplyingMD5HashesToAssetsAllRelevantSourceFilesMustBeUpdatedCorrectly()
        {
            CacheBuster.AssetFolderPaths = new List<string> { CacheBusterBustingTestPath + @"Web\Source\Assets\" };
            CacheBuster.SourceFolderPaths = new List<string> { CacheBusterBustingTestPath + @"Web\Source\" };
            CacheBuster.SourceRootPath = CacheBusterBustingTestPath + @"Web\Source\";
            CacheBuster.Command = CacheBuster.CommandType.CacheBust;
            CacheBuster.DeleteOldFileVersions = true;
            CacheBuster.SourceFileExtensionsFilter = new List<string> { ".png" };
            CacheBuster.SourceFileExtensionsFilterType = CacheBuster.Filter.Exclude;
            CacheBuster.IncludedDomainNames = new List<string> { "anincludeddomainname.com" };
            CacheBuster.OutputFilePath = CacheBusterBustingTestPath + "OutputFile.txt";

            CacheBuster.Go();

            // Need to assert relevant asset files have been renamed
            Assert.IsTrue(File.Exists(CacheBusterBustingTestPath + @"Web\Source\Assets\Css\Screen_MD5_4884e9f75a189921f75a5850e28e8400.css"));
            Assert.IsFalse(File.Exists(CacheBusterBustingTestPath + @"Web\Source\Assets\Css\Screen.css"));
            Assert.IsTrue(File.Exists(CacheBusterBustingTestPath + @"Web\Source\Assets\FolderOne\Asset_MD5_e5a38cca2ff1ffb2f7a2c9d6cfeb4718.txt"));
            Assert.IsFalse(File.Exists(CacheBusterBustingTestPath + @"Web\Source\Assets\FolderOne\Asset.txt"));
            Assert.IsTrue(File.Exists(CacheBusterBustingTestPath + @"Web\Source\Assets\FolderOne\AnotherAsset_MD5_b4e9148036eeb1a36ac4fc3ab387369d.txt"));
            Assert.IsFalse(File.Exists(CacheBusterBustingTestPath + @"Web\Source\Assets\FolderOne\AnotherAsset_MD5_bba38cca2ff1fgb2f7a2c9d6cfeb4732.txt"));
            Assert.IsTrue(File.Exists(CacheBusterBustingTestPath + @"Web\Source\Assets\FolderTwo\Asset_MD5_076819f2f917c81288d5772942ab177c.txt"));
            Assert.IsFalse(File.Exists(CacheBusterBustingTestPath + @"Web\Source\Assets\FolderTwo\Asset.txt"));
            Assert.IsTrue(File.Exists(CacheBusterBustingTestPath + @"Web\Source\Assets\Images\main_background_MD5_2abd72c7cdcbd49ceef0d6625bf2ecf8.png"));
            Assert.IsFalse(File.Exists(CacheBusterBustingTestPath + @"Web\Source\Assets\Images\main_background.png"));
            Assert.IsTrue(File.Exists(CacheBusterBustingTestPath + @"Web\Source\Assets\Images\bgs\sprite_MD5_eea431a360e80a1dfb88e58d837707e3.png"));
            Assert.IsFalse(File.Exists(CacheBusterBustingTestPath + @"Web\Source\Assets\Images\bgs\sprite.png"));

            Assert.IsTrue(File.Exists(CacheBusterBustingTestPath + "OutputFile.txt"));

            // Add relevant asserts to compare file content
            string screenCssExpectedContent = File.ReadAllText(CacheBusterBustingTestPath + @"Expected\Web_Source_Assets_Screen.css");
            string screenCssActualContent = File.ReadAllText(CacheBusterBustingTestPath + @"Web\Source\Assets\Css\Screen_MD5_4884e9f75a189921f75a5850e28e8400.css");
            Assert.AreEqual(screenCssExpectedContent, screenCssActualContent);

            string sourceFileExpectedContent = File.ReadAllText(CacheBusterBustingTestPath + @"Expected\Web_Source_SourceFile.aspx");
            string sourceFileActualContent = File.ReadAllText(CacheBusterBustingTestPath + @"Web\Source\SourceFile.aspx");
            Assert.AreEqual(sourceFileExpectedContent, sourceFileActualContent);

            string defaultExpectedContent = File.ReadAllText(CacheBusterBustingTestPath + @"Expected\Web_Source_Templates_Pages_Default.aspx");
            string defaultActualContent = File.ReadAllText(CacheBusterBustingTestPath + @"Web\Source\Templates\Pages\Default.aspx");
            Assert.AreEqual(defaultExpectedContent, defaultActualContent);

            string projectsFileExpectedContent = File.ReadAllText(CacheBusterBustingTestPath + @"Expected\Web_Source_Project.csproj");
            string projectsFileActualContent = File.ReadAllText(CacheBusterBustingTestPath + @"Web\Source\Project.csproj");
            Assert.AreEqual(projectsFileExpectedContent, projectsFileActualContent);
        }

        [Test]
        public void WhenCacheBustingAssetsThatAreAlsoSourceFilesVerifyThatUpdatedSourceFilesAreRehashedAndReferencingSourceFilesAreAlsoUpdated()
        {
            CacheBuster.AssetFolderPaths = new List<string> { CacheBusterBustingTestThreePath + @"Web\Assets\" };
            CacheBuster.SourceFolderPaths = new List<string> { CacheBusterBustingTestThreePath + @"Web\" };
            CacheBuster.SourceRootPath = CacheBusterBustingTestThreePath + @"Web\";
            CacheBuster.Command = CacheBuster.CommandType.CacheBust;
            CacheBuster.DeleteOldFileVersions = true;
            CacheBuster.SourceFileExtensionsFilter = new List<string> { ".png" };
            CacheBuster.SourceFileExtensionsFilterType = CacheBuster.Filter.Exclude;
            CacheBuster.OutputFilePath = CacheBusterBustingTestThreePath + "OutputFile.txt";

            CacheBuster.Go();

            Assert.IsTrue(File.Exists(CacheBusterBustingTestThreePath + @"Web\Assets\Style_MD5_6da8c8f22646cf61ff2886bb55bbdc6c.css"));
            Assert.IsFalse(File.Exists(CacheBusterBustingTestThreePath + @"Web\Source\Assets\Style.css"));
            Assert.IsTrue(File.Exists(CacheBusterBustingTestThreePath + @"Web\Assets\image_MD5_a4f8d5262845cfb603f34e219ebccef9.png"));
            Assert.IsFalse(File.Exists(CacheBusterBustingTestThreePath + @"Web\Source\Assets\image.png"));

            Assert.IsTrue(File.Exists(CacheBusterBustingTestThreePath + "OutputFile.txt"));

            string styleCssExpectedContent = File.ReadAllText(CacheBusterBustingTestThreePath + @"Expected\Style.css");
            string styleCssActualContent = File.ReadAllText(CacheBusterBustingTestThreePath + @"Web\Assets\Style_MD5_6da8c8f22646cf61ff2886bb55bbdc6c.css");
            Assert.AreEqual(styleCssExpectedContent, styleCssActualContent);

            string sourceFileExpectedContent = File.ReadAllText(CacheBusterBustingTestThreePath + @"Expected\Default.aspx");
            string sourceFileActualContent = File.ReadAllText(CacheBusterBustingTestThreePath + @"Web\Default.aspx");
            Assert.AreEqual(sourceFileExpectedContent, sourceFileActualContent);
        }

        [Test]
        public void WhenApplyingVersionNumbersToAssetsAllRelevantSourcefilesMustBeUpdatedCorrectly()
        {
            CacheBuster.AssetFolderPaths = new List<string> { CacheBusterBustingTestFourPath + @"Web\Assets\" };
            CacheBuster.SourceFolderPaths = new List<string> { CacheBusterBustingTestFourPath + @"Web\" };
            CacheBuster.SourceRootPath = CacheBusterBustingTestFourPath + @"Web\";
            CacheBuster.Command = CacheBuster.CommandType.CacheBust;
            CacheBuster.CacheBustingType = CacheBuster.CacheBustType.Version;
            CacheBuster.DeleteOldFileVersions = true;
            CacheBuster.SourceFileExtensionsFilter = new List<string> { ".png" };
            CacheBuster.SourceFileExtensionsFilterType = CacheBuster.Filter.Exclude;
            CacheBuster.OutputFilePath = CacheBusterBustingTestFourPath + "OutputFile.txt";
            CacheBuster.VersionFilePath = CacheBusterBustingTestFourPath + "Versions.xml";

            CacheBuster.Go();

            Assert.IsTrue(File.Exists(CacheBusterBustingTestFourPath + @"Web\Assets\image_v1.png"));
            Assert.IsFalse(File.Exists(CacheBusterBustingTestFourPath + @"Web\Assets\image.png"));
            Assert.IsTrue(File.Exists(CacheBusterBustingTestFourPath + @"Web\Assets\Style_v7.css"));
            Assert.IsFalse(File.Exists(CacheBusterBustingTestFourPath + @"Web\Assets\Style.css"));
            Assert.IsTrue(File.Exists(CacheBusterBustingTestFourPath + @"Web\Assets\Style2_v5.css"));
            Assert.IsFalse(File.Exists(CacheBusterBustingTestFourPath + @"Web\Assets\Style2.css"));

            Assert.IsTrue(File.Exists(CacheBusterBustingTestFourPath + "OutputFile.txt"));

            string sourceFileExpectedContent = File.ReadAllText(CacheBusterBustingTestFourPath + @"Expected\Default.aspx");
            string sourceFileActualContent = File.ReadAllText(CacheBusterBustingTestFourPath + @"Web\Default.aspx");
            Assert.AreEqual(sourceFileExpectedContent, sourceFileActualContent);

            string cssFileExpectedContent = File.ReadAllText(CacheBusterBustingTestFourPath + @"Expected\Style.css");
            string cssFileActualContent = File.ReadAllText(CacheBusterBustingTestFourPath + @"Web\Assets\Style_v7.css");
            Assert.AreEqual(cssFileExpectedContent, cssFileActualContent);

            cssFileExpectedContent = File.ReadAllText(CacheBusterBustingTestFourPath + @"Expected\Style2.css");
            cssFileActualContent = File.ReadAllText(CacheBusterBustingTestFourPath + @"Web\Assets\Style2_v5.css");
            Assert.AreEqual(cssFileExpectedContent, cssFileActualContent);

            XmlDocument doc = new XmlDocument();
            doc.Load(CacheBusterBustingTestFourPath + "Versions.xml");
            XmlNodeList nodes = doc.SelectNodes("/versions/file");
            Assert.AreEqual(3, nodes.Count);

            XmlNode node = nodes.Cast<XmlNode>().FirstOrDefault(x => x.Attributes["filePath"].Value == @"c:\temp\browsercachebustertestdatafour\web\assets\style.css");
            Assert.IsNotNull(node);
            Assert.AreEqual("7", node.Attributes["versionNumber"].Value);

            node = nodes.Cast<XmlNode>().FirstOrDefault(x => x.Attributes["filePath"].Value == @"c:\temp\browsercachebustertestdatafour\web\assets\style2.css");
            Assert.IsNotNull(node);
            Assert.AreEqual("5", node.Attributes["versionNumber"].Value);

            node = nodes.Cast<XmlNode>().FirstOrDefault(x => x.Attributes["filePath"].Value == @"c:\temp\browsercachebustertestdatafour\web\assets\image.png");
            Assert.IsNotNull(node);
            Assert.AreEqual("1", node.Attributes["versionNumber"].Value);
        }

        [Test]
        public void WhenApplyingHashToAnAssetAViewFileMakingUseOfDotDotPathsMustBeUpdatedCorrectly()
        {
            CacheBuster.AssetFolderPaths = new List<string> { CacheBusterBustingTestFivePath + @"Web\Assets\" };
            CacheBuster.SourceFolderPaths = new List<string> { CacheBusterBustingTestFivePath + @"Web\" };
            CacheBuster.SourceRootPath = CacheBusterBustingTestFivePath + @"Web\";
            CacheBuster.Command = CacheBuster.CommandType.CacheBust;
            CacheBuster.DeleteOldFileVersions = true;
            CacheBuster.OutputFilePath = CacheBusterBustingTestPath + "OutputFile.txt";

            CacheBuster.Go();

            Assert.IsTrue(File.Exists(CacheBusterBustingTestFivePath + @"Web\Assets\image_MD5_a4f8d5262845cfb603f34e219ebccef9.png"));

            string sourceFileExpectedContent = File.ReadAllText(CacheBusterBustingTestFivePath + @"Expected\Default.cshtml");
            string sourceFileActualContent = File.ReadAllText(CacheBusterBustingTestFivePath + @"Web\Views\Login\Default.cshtml");
            Assert.AreEqual(sourceFileExpectedContent, sourceFileActualContent);
        }

        #endregion CacheBuster Tests

        #region File manager tests

        [Test]
        public void FileManagerGetFilesWithFileNamesInclusionFilters()
        {
            FileSearchData fileSearchData = new FileSearchData();
            fileSearchData.FolderPaths.Add(CacheBusterTestAssetsPath);
            fileSearchData.FileNamesFilter = new List<string> { "Notes.txt" };
            fileSearchData.FileNamesFilterType = CacheBuster.Filter.Include;

            var files = FileManager.GetFiles(fileSearchData);

            Assert.AreEqual(1, files.Count);
            Assert.AreEqual("Notes.txt", files[0].Name);
        }

        [Test]
        public void FileManagerGetFilesWithFilePathsInclusionFilters()
        {
            FileSearchData fileSearchData = new FileSearchData();
            fileSearchData.FolderPaths.Add(CacheBusterTestAssetsPath);
            fileSearchData.FilePathsFilter = new List<string> { CacheBusterTestAssetsPath + @"Styles\IE6.css" };
            fileSearchData.FilePathsFilterType = CacheBuster.Filter.Include;

            var files = FileManager.GetFiles(fileSearchData);

            Assert.AreEqual(1, files.Count);
            Assert.AreEqual("IE6.css", files[0].Name);
        }

        [Test]
        public void FileManagerGetFilesWithFileExtensionsInclusionFilters()
        {
            FileSearchData fileSearchData = new FileSearchData();
            fileSearchData.FolderPaths.Add(CacheBusterTestAssetsPath);
            fileSearchData.FileExtensionsFilter = new List<string> { ".png" };
            fileSearchData.FileExtensionsFilterType = CacheBuster.Filter.Include;

            var files = FileManager.GetFiles(fileSearchData);

            Assert.AreEqual(2, files.Count);
            Assert.IsTrue(files.Any(c => string.Equals("imageone.png", c.Name)));
            Assert.IsTrue(files.Any(c => string.Equals("imgtwo.png", c.Name)));
        }

        [Test]
        public void FileManagerGetFilesWithFileNamesExclusionFilters()
        {
            FileSearchData fileSearchData = new FileSearchData();
            fileSearchData.FolderPaths.Add(CacheBusterTestAssetsPath);
            fileSearchData.FileNamesFilter = new List<string> { "Notes.txt" };
            fileSearchData.FileNamesFilterType = CacheBuster.Filter.Exclude;

            var files = FileManager.GetFiles(fileSearchData);

            Assert.AreEqual(9, files.Count);
            Assert.IsFalse(files.Any(c => string.Equals("Notes.txt", c.Name)));
        }

        [Test]
        public void FileManagerGetFilesWithFilePathsExclusionFilters()
        {
            FileSearchData fileSearchData = new FileSearchData();
            fileSearchData.FolderPaths.Add(CacheBusterTestAssetsPath);
            fileSearchData.FilePathsFilter = new List<string> { CacheBusterTestAssetsPath + @"Styles\IE6.css" };
            fileSearchData.FilePathsFilterType = CacheBuster.Filter.Exclude;

            var files = FileManager.GetFiles(fileSearchData);

            Assert.AreEqual(9, files.Count);
            Assert.IsFalse(files.Any(c => string.Equals("IE6.css", c.Name)));
        }

        [Test]
        public void FileManagerGetFilesWithFileExclusionInclusionFilters()
        {
            FileSearchData fileSearchData = new FileSearchData();
            fileSearchData.FolderPaths.Add(CacheBusterTestAssetsPath);
            fileSearchData.FileExtensionsFilter = new List<string> { ".png" };
            fileSearchData.FileExtensionsFilterType = CacheBuster.Filter.Exclude;

            var files = FileManager.GetFiles(fileSearchData);

            Assert.AreEqual(8, files.Count);
            Assert.IsFalse(files.Any(c => string.Equals("imageone.png", c.Name)));
            Assert.IsFalse(files.Any(c => string.Equals("imgtwo.png", c.Name)));
        }

        [Test]
        public void FileManagerGetFilesWithNoFilters()
        {
            FileSearchData fileSearchData = new FileSearchData();
            fileSearchData.FolderPaths.Add(CacheBusterTestAssetsPath);

            var files = FileManager.GetFiles(fileSearchData);

            Assert.AreEqual(10, files.Count);
        }

        #endregion File manager tests

        #region CacheBuster internal method tests

        [Test]
        public void TestMd5HashGeneration()
        {
            string hash = FileManager.ComputeMd5Hash(CacheBusterTestAssetsPath + "Notes.txt");
            Assert.AreEqual("6831e4ee158eea280b94986561f3d008", hash);

            hash = FileManager.ComputeMd5Hash(CacheBusterTestAssetsPath + @"Styles\Screen.css");
            Assert.AreEqual("d24277ca69591c50b3e8eba17a073791", hash);
        }

        [Test]
        public void TestGetFileHash()
        {
            string hash = FileManager.GetFileHash(CacheBusterTestAssetsPath + "Notes.txt");
            Assert.AreEqual(string.Empty, hash);

            hash = FileManager.GetFileHash(CacheBusterTestAssetsPath + "NotesWithHash_MD5_6831e4ee158eea280b94986561f3d008.txt");
            Assert.AreEqual("6831e4ee158eea280b94986561f3d008", hash);

            CacheBuster.MD5HashPrefix = "_";
            hash = FileManager.GetFileHash(CacheBusterTestAssetsPath + "NotesWithHash_6831e4ee158eea280b94986561f3d008.txt");
            Assert.AreEqual("6831e4ee158eea280b94986561f3d008", hash);

            CacheBuster.MD5HashPrefix = string.Empty;
            hash = FileManager.GetFileHash(CacheBusterTestAssetsPath + "NotesWithHash_6831e4ee158eea280b94986561f3d008.txt");
            Assert.AreEqual("6831e4ee158eea280b94986561f3d008", hash);

            hash = FileManager.GetFileHash(CacheBusterTestAssetsPath + "NotesWithHash_cheese_6831e4ee158eea280b94986561f3d008.txt");
            Assert.AreEqual("6831e4ee158eea280b94986561f3d008", hash);
        }

        [Test]
        public void TestGetNewFileName()
        {
            string hash = FileManager.GetFileHash(CacheBusterTestAssetsPath + "NotesWithInvalidHash_MD5_6831e4ee158eea280b94986561f3d008.txt");
            string newFileName = FileManager.GetNewFileName(CacheBusterTestAssetsPath + "NotesWithInvalidHash_MD5_6831e4ee158eea280b94986561f3d008.txt", hash);
            Assert.AreEqual(CacheBusterTestPath + @"Assets\NotesWithInvalidHash_MD5_6831e4ee158eea280b94986561f3d008.txt", newFileName);

            newFileName = FileManager.GetNewFileName(CacheBusterTestAssetsPath + "Notes.txt", hash);
            Assert.AreEqual(CacheBusterTestPath + @"Assets\Notes_MD5_6831e4ee158eea280b94986561f3d008.txt", newFileName);

            CacheBuster.MD5HashPrefix = "_";

            newFileName = FileManager.GetNewFileName(CacheBusterTestAssetsPath + "Notes.txt", hash);
            Assert.AreEqual(CacheBusterTestPath + @"Assets\Notes_6831e4ee158eea280b94986561f3d008.txt", newFileName);

            newFileName = FileManager.GetNewFileName(CacheBusterTestAssetsPath + "Notes_cheese.txt", hash);
            Assert.AreEqual(CacheBusterTestPath + @"Assets\Notes_6831e4ee158eea280b94986561f3d008.txt", newFileName);
        }

        [Test]
        public void TestHashAssetsWithoutDeletingFiles()
        {
            CacheBuster.ResetArguments();
            CacheBuster.AssetFolderPaths = new List<string> { CacheBusterTestAssetsPath };
            CacheBuster.SourceFolderPaths = new List<string> { CacheBusterTestSourcePath, CacheBusterTestAlternativeSourcePath };
            CacheBuster.Command = CacheBuster.CommandType.CacheBust;

            CacheBuster.Output = new StringBuilderOutput();
            CacheBuster.FindAssetAndSourceFiles();
            CacheBuster.HashAssets(CacheBuster.AssetFiles);
            CacheBuster.FindAssetAndSourceFiles();

            Assert.AreEqual(19, CacheBuster.AssetFiles.Count);
            Assert.IsTrue(CacheBuster.AssetFiles.Any(c => string.Equals(c.OriginalFilePath, CacheBusterTestAssetsPath + "Notes.txt", StringComparison.CurrentCultureIgnoreCase)));
            Assert.IsTrue(CacheBuster.AssetFiles.Any(c => string.Equals(c.OriginalFilePath, CacheBusterTestAssetsPath + "Notes_MD5_6831e4ee158eea280b94986561f3d008.txt", StringComparison.CurrentCultureIgnoreCase)));
            Assert.IsTrue(CacheBuster.AssetFiles.Any(c => string.Equals(c.OriginalFilePath, CacheBusterTestAssetsPath + "NotesWithHash_MD5_6831e4ee158eea280b94986561f3d008.txt", StringComparison.CurrentCultureIgnoreCase)));
            Assert.IsTrue(CacheBuster.AssetFiles.Any(c => string.Equals(c.OriginalFilePath, CacheBusterTestAssetsPath + "NotesWithInvalidHash_MD5_6831e4ee158eea280b94986561f3d008.txt", StringComparison.CurrentCultureIgnoreCase)));
            Assert.IsTrue(CacheBuster.AssetFiles.Any(c => string.Equals(c.OriginalFilePath, CacheBusterTestAssetsPath + "NotesWithInvalidHash_MD5_565220ee2fb066acff001e28f7383437.txt", StringComparison.CurrentCultureIgnoreCase)));
            Assert.IsTrue(CacheBuster.AssetFiles.Any(c => string.Equals(c.OriginalFilePath, CacheBusterTestAssetsPath + @"Images\imageone.jpg", StringComparison.CurrentCultureIgnoreCase)));
            Assert.IsTrue(CacheBuster.AssetFiles.Any(c => string.Equals(c.OriginalFilePath, CacheBusterTestAssetsPath + @"Images\imageone.png", StringComparison.CurrentCultureIgnoreCase)));
            Assert.IsTrue(CacheBuster.AssetFiles.Any(c => string.Equals(c.OriginalFilePath, CacheBusterTestAssetsPath + @"Images\imageone_MD5_d41d8cd98f00b204e9800998ecf8427e.jpg", StringComparison.CurrentCultureIgnoreCase)));
            Assert.IsTrue(CacheBuster.AssetFiles.Any(c => string.Equals(c.OriginalFilePath, CacheBusterTestAssetsPath + @"Images\imageone_MD5_d41d8cd98f00b204e9800998ecf8427e.png", StringComparison.CurrentCultureIgnoreCase)));
            Assert.IsTrue(CacheBuster.AssetFiles.Any(c => string.Equals(c.OriginalFilePath, CacheBusterTestAssetsPath + @"Images\imgtwo.png", StringComparison.CurrentCultureIgnoreCase)));
            Assert.IsTrue(CacheBuster.AssetFiles.Any(c => string.Equals(c.OriginalFilePath, CacheBusterTestAssetsPath + @"Images\imgtwo_MD5_d41d8cd98f00b204e9800998ecf8427e.png", StringComparison.CurrentCultureIgnoreCase)));
            Assert.IsTrue(CacheBuster.AssetFiles.Any(c => string.Equals(c.OriginalFilePath, CacheBusterTestAssetsPath + @"Styles\IE6.css", StringComparison.CurrentCultureIgnoreCase)));
            Assert.IsTrue(CacheBuster.AssetFiles.Any(c => string.Equals(c.OriginalFilePath, CacheBusterTestAssetsPath + @"Styles\IE6_MD5_d41d8cd98f00b204e9800998ecf8427e.css", StringComparison.CurrentCultureIgnoreCase)));
            Assert.IsTrue(CacheBuster.AssetFiles.Any(c => string.Equals(c.OriginalFilePath, CacheBusterTestAssetsPath + @"Styles\IE8.css", StringComparison.CurrentCultureIgnoreCase)));
            Assert.IsTrue(CacheBuster.AssetFiles.Any(c => string.Equals(c.OriginalFilePath, CacheBusterTestAssetsPath + @"Styles\IE8_MD5_d41d8cd98f00b204e9800998ecf8427e.css", StringComparison.CurrentCultureIgnoreCase)));
            Assert.IsTrue(CacheBuster.AssetFiles.Any(c => string.Equals(c.OriginalFilePath, CacheBusterTestAssetsPath + @"Styles\Screen.css", StringComparison.CurrentCultureIgnoreCase)));
            Assert.IsTrue(CacheBuster.AssetFiles.Any(c => string.Equals(c.OriginalFilePath, CacheBusterTestAssetsPath + @"Styles\Screen_MD5_d24277ca69591c50b3e8eba17a073791.css", StringComparison.CurrentCultureIgnoreCase)));
            Assert.IsTrue(CacheBuster.AssetFiles.Any(c => string.Equals(c.OriginalFilePath, CacheBusterTestAssetsPath + @"Styles\Specific\Lightbox.css", StringComparison.CurrentCultureIgnoreCase)));
            Assert.IsTrue(CacheBuster.AssetFiles.Any(c => string.Equals(c.OriginalFilePath, CacheBusterTestAssetsPath + @"Styles\Specific\Lightbox_MD5_d41d8cd98f00b204e9800998ecf8427e.css", StringComparison.CurrentCultureIgnoreCase)));
        }

        [Test]
        public void TestHashAssetsWithDeletingFiles()
        {
            CacheBuster.ResetArguments();
            CacheBuster.AssetFolderPaths = new List<string> { CacheBusterTestAssetsPath };
            CacheBuster.SourceFolderPaths = new List<string> { CacheBusterTestSourcePath, CacheBusterTestAlternativeSourcePath };
            CacheBuster.Command = CacheBuster.CommandType.CacheBust;
            CacheBuster.DeleteOldFileVersions = true;

            CacheBuster.Output = new StringBuilderOutput();
            string output = CacheBuster.Output.Data.ToString();

            CacheBuster.FindAssetAndSourceFiles();
            CacheBuster.HashAssets(CacheBuster.AssetFiles);

            CacheBuster.FindAssetAndSourceFiles();

            Assert.AreEqual(10, CacheBuster.AssetFiles.Count);
            Assert.IsTrue(CacheBuster.AssetFiles.Any(c => string.Equals(c.OriginalFilePath, CacheBusterTestAssetsPath + "Notes_MD5_6831e4ee158eea280b94986561f3d008.txt", StringComparison.CurrentCultureIgnoreCase)));
            Assert.IsTrue(CacheBuster.AssetFiles.Any(c => string.Equals(c.OriginalFilePath, CacheBusterTestAssetsPath + "NotesWithHash_MD5_6831e4ee158eea280b94986561f3d008.txt", StringComparison.CurrentCultureIgnoreCase)));
            Assert.IsTrue(CacheBuster.AssetFiles.Any(c => string.Equals(c.OriginalFilePath, CacheBusterTestAssetsPath + "NotesWithInvalidHash_MD5_565220ee2fb066acff001e28f7383437.txt", StringComparison.CurrentCultureIgnoreCase)));
            Assert.IsTrue(CacheBuster.AssetFiles.Any(c => string.Equals(c.OriginalFilePath, CacheBusterTestAssetsPath + @"Images\imageone_MD5_d41d8cd98f00b204e9800998ecf8427e.jpg", StringComparison.CurrentCultureIgnoreCase)));
            Assert.IsTrue(CacheBuster.AssetFiles.Any(c => string.Equals(c.OriginalFilePath, CacheBusterTestAssetsPath + @"Images\imageone_MD5_d41d8cd98f00b204e9800998ecf8427e.png", StringComparison.CurrentCultureIgnoreCase)));
            Assert.IsTrue(CacheBuster.AssetFiles.Any(c => string.Equals(c.OriginalFilePath, CacheBusterTestAssetsPath + @"Images\imgtwo_MD5_d41d8cd98f00b204e9800998ecf8427e.png", StringComparison.CurrentCultureIgnoreCase)));
            Assert.IsTrue(CacheBuster.AssetFiles.Any(c => string.Equals(c.OriginalFilePath, CacheBusterTestAssetsPath + @"Styles\IE6_MD5_d41d8cd98f00b204e9800998ecf8427e.css", StringComparison.CurrentCultureIgnoreCase)));
            Assert.IsTrue(CacheBuster.AssetFiles.Any(c => string.Equals(c.OriginalFilePath, CacheBusterTestAssetsPath + @"Styles\IE8_MD5_d41d8cd98f00b204e9800998ecf8427e.css", StringComparison.CurrentCultureIgnoreCase)));
            Assert.IsTrue(CacheBuster.AssetFiles.Any(c => string.Equals(c.OriginalFilePath, CacheBusterTestAssetsPath + @"Styles\Screen_MD5_d24277ca69591c50b3e8eba17a073791.css", StringComparison.CurrentCultureIgnoreCase)));
            Assert.IsTrue(CacheBuster.AssetFiles.Any(c => string.Equals(c.OriginalFilePath, CacheBusterTestAssetsPath + @"Styles\Specific\Lightbox_MD5_d41d8cd98f00b204e9800998ecf8427e.css", StringComparison.CurrentCultureIgnoreCase)));
        }

        #endregion CacheBuster internal method tests

        #region VersionManager tests

        [Test]
        public void VersionManagerGetFileVersionNumber()
        {
            int? versionNumber = VersionManager.GetFileVersionNumber("c:\temp\test.txt");
            Assert.IsTrue(!versionNumber.HasValue);

            versionNumber = VersionManager.GetFileVersionNumber("c:\temp\test");
            Assert.IsTrue(!versionNumber.HasValue);

            versionNumber = VersionManager.GetFileVersionNumber("c:\temp\test_v-1");
            Assert.IsTrue(!versionNumber.HasValue);

            versionNumber = VersionManager.GetFileVersionNumber("c:\temp\test_v1");
            Assert.AreEqual(1, versionNumber.Value);

            versionNumber = VersionManager.GetFileVersionNumber("c:\temp\test_v1.txt");
            Assert.AreEqual(1, versionNumber.Value);

            versionNumber = VersionManager.GetFileVersionNumber("c:\temp\test_v27.txt");
            Assert.AreEqual(27, versionNumber.Value);

            versionNumber = VersionManager.GetFileVersionNumber("c:\temp\test_v27a.txt");
            Assert.IsTrue(!versionNumber.HasValue);
        }

        [Test]
        public void VersionManagerGetFilePathWithVersionNumber()
        {
            string filePath = VersionManager.GetFilePathWithVersionNumber("c:\temp\test.txt", 4);
            Assert.AreEqual("c:\temp\test_v4.txt", filePath);

            filePath = VersionManager.GetFilePathWithVersionNumber("c:\temp\test_v3.txt", 4);
            Assert.AreEqual("c:\temp\test_v4.txt", filePath);

            filePath = VersionManager.GetFilePathWithVersionNumber("c:\temp\test", 4);
            Assert.AreEqual("c:\temp\test_v4", filePath);

            filePath = VersionManager.GetFilePathWithVersionNumber("c:\temp\test_v3", 4);
            Assert.AreEqual("c:\temp\test_v4", filePath);
        }

        [Test]
        public void VersionManagerXmlDocumentTests()
        {
            VersionManager.VersionFilePath = CacheBusterBustingTestThreePath + "Versions.xml";

            FileVersion fileVersion = new FileVersion();
            fileVersion.FilePath = @"c:\temp\test.txt";
            fileVersion.VersionNumber = 1;
            fileVersion.Hash = "thisisthehash";
            VersionManager.AddFileVersion(fileVersion);

            fileVersion = new FileVersion();
            fileVersion.FilePath = @"c:\temp\test2.txt";
            fileVersion.VersionNumber = 2;
            fileVersion.Hash = "thisisanotherhash";
            VersionManager.AddFileVersion(fileVersion);

            VersionManager.Save();

            VersionManager.Loaded = false;

            fileVersion = VersionManager.FindFileVersion(@"c:\temp\test3.txt");
            Assert.IsNull(fileVersion);

            fileVersion = VersionManager.FindFileVersion(@"c:\temp\test.txt");
            Assert.IsNotNull(fileVersion);
            Assert.AreEqual(@"c:\temp\test.txt", fileVersion.FilePath);
            Assert.AreEqual(1, fileVersion.VersionNumber);
            Assert.AreEqual("thisisthehash", fileVersion.Hash);

            fileVersion = VersionManager.FindFileVersion(@"c:\temp\test2.txt");
            Assert.IsNotNull(fileVersion);
            Assert.AreEqual(@"c:\temp\test2.txt", fileVersion.FilePath);
            Assert.AreEqual(2, fileVersion.VersionNumber);
            Assert.AreEqual("thisisanotherhash", fileVersion.Hash);

            fileVersion.VersionNumber = 4;
            fileVersion.Hash = "theupdatedhash";

            VersionManager.UpdateFileVersion(fileVersion);
            VersionManager.Save();

            VersionManager.Loaded = false;

            fileVersion = VersionManager.FindFileVersion(@"c:\temp\test.txt");
            Assert.IsNotNull(fileVersion);
            Assert.AreEqual(@"c:\temp\test.txt", fileVersion.FilePath);
            Assert.AreEqual(1, fileVersion.VersionNumber);
            Assert.AreEqual("thisisthehash", fileVersion.Hash);

            fileVersion = VersionManager.FindFileVersion(@"c:\temp\test2.txt");
            Assert.IsNotNull(fileVersion);
            Assert.AreEqual(@"c:\temp\test2.txt", fileVersion.FilePath);
            Assert.AreEqual(4, fileVersion.VersionNumber);
            Assert.AreEqual("theupdatedhash", fileVersion.Hash);
        }

        #endregion VersionManager tests

        #region Clean up tests

        private void CreateTestFile(string fileName)
        {
            System.Threading.Thread.Sleep(20);
            File.WriteAllText(fileName, string.Empty);
        }

        private void CopyTestFile(string from, string to)
        {
            System.Threading.Thread.Sleep(20);
            File.Copy(from, to);
        }

        [Test]
        public void WhenCleaningUpAssetsUsingHashesOldVersionsShouldBeCleanedUpCorrectly()
        {
            CreateTestFile(CacheBusterBustingTestSixPath + "FileOne.txt");

            CreateTestFile(CacheBusterBustingTestSixPath + "FileTwo.txt");
            CopyTestFile(CacheBusterBustingTestSixPath + "FileTwo.txt", CacheBusterBustingTestSixPath + "FileTwo__asdfweruioyweroi38u3.txt");

            CreateTestFile(CacheBusterBustingTestSixPath + "FileThree.txt");
            CopyTestFile(CacheBusterBustingTestSixPath + "FileThree.txt", CacheBusterBustingTestSixPath + "FileThree__asdfweruioyweroi38u3.txt");
            CopyTestFile(CacheBusterBustingTestSixPath + "FileThree.txt", CacheBusterBustingTestSixPath + "FileThree__wer45srfgas34r324awe.txt");

            CreateTestFile(CacheBusterBustingTestSixPath + "FileFour.txt");
            CopyTestFile(CacheBusterBustingTestSixPath + "FileFour.txt", CacheBusterBustingTestSixPath + "FileFour__asdfweruioyweroi38u3.txt");
            CopyTestFile(CacheBusterBustingTestSixPath + "FileFour.txt", CacheBusterBustingTestSixPath + "FileFour__wer45srfgas34r324awe.txt");
            CopyTestFile(CacheBusterBustingTestSixPath + "FileFour.txt", CacheBusterBustingTestSixPath + "FileFour__2309ujowseolijlqiejr.txt");

            CreateTestFile(CacheBusterBustingTestSixPath + "FileFive.txt");
            CopyTestFile(CacheBusterBustingTestSixPath + "FileFive.txt", CacheBusterBustingTestSixPath + "FileFive__asdfweruioyweroi38u3.txt");
            CopyTestFile(CacheBusterBustingTestSixPath + "FileFive.txt", CacheBusterBustingTestSixPath + "FileFive__wer45srfgas34r324awe.txt");
            CopyTestFile(CacheBusterBustingTestSixPath + "FileFive.txt", CacheBusterBustingTestSixPath + "FileFive__2309ujowseolijlqiejr.txt");
            CopyTestFile(CacheBusterBustingTestSixPath + "FileFive.txt", CacheBusterBustingTestSixPath + "FileFive__sfdewfsdf098903sdfsd.txt");
            
            List<FileInfo> files = new DirectoryInfo(CacheBusterBustingTestSixPath).GetFiles("*.*", SearchOption.AllDirectories).ToList();
            Assert.AreEqual(15, files.Count);

            string[] arguments = new[]
                                     {
                                         "-afp:" + CacheBusterBustingTestSixPath,
                                         "-c:2",
                                         "-hp:__",
                                         "-k:2"
                                     };

            CacheBuster.ProcessCommandLineArguments(arguments);
            CacheBuster.Go();

            // assert that relevant files exist and have been deleted etc
            files = new DirectoryInfo(CacheBusterBustingTestSixPath).GetFiles("*.*", SearchOption.AllDirectories).ToList();

            Assert.AreEqual(9, files.Count);

            // assert all nine files exist
            Assert.IsTrue(files.Any(c => c.Name == "FileOne.txt"));
            Assert.IsTrue(files.Any(c => c.Name == "FileTwo.txt"));
            Assert.IsTrue(files.Any(c => c.Name == "FileTwo__asdfweruioyweroi38u3.txt"));
            Assert.IsTrue(files.Any(c => c.Name == "FileThree__asdfweruioyweroi38u3.txt"));
            Assert.IsTrue(files.Any(c => c.Name == "FileThree__wer45srfgas34r324awe.txt"));
            Assert.IsTrue(files.Any(c => c.Name == "FileFour__wer45srfgas34r324awe.txt"));
            Assert.IsTrue(files.Any(c => c.Name == "FileFour__2309ujowseolijlqiejr.txt"));
            Assert.IsTrue(files.Any(c => c.Name == "FileFive__2309ujowseolijlqiejr.txt"));
            Assert.IsTrue(files.Any(c => c.Name == "FileFive__sfdewfsdf098903sdfsd.txt"));
        }

        [Test]
        public void WhenCleaningUpAssetsUsingVersionNumbersOldVersionsShouldBeCleanedUpCorrectly()
        {
            CreateTestFile(CacheBusterBustingTestSixPath + "FileOne.txt");

            CreateTestFile(CacheBusterBustingTestSixPath + "FileTwo.txt");
            CopyTestFile(CacheBusterBustingTestSixPath + "FileTwo.txt", CacheBusterBustingTestSixPath + "FileTwo_v1.txt");

            CreateTestFile(CacheBusterBustingTestSixPath + "FileThree.txt");
            CopyTestFile(CacheBusterBustingTestSixPath + "FileThree.txt", CacheBusterBustingTestSixPath + "FileThree_v4.txt");
            CopyTestFile(CacheBusterBustingTestSixPath + "FileThree.txt", CacheBusterBustingTestSixPath + "FileThree_v3.txt");

            CreateTestFile(CacheBusterBustingTestSixPath + "FileFour.txt");
            CopyTestFile(CacheBusterBustingTestSixPath + "FileFour.txt", CacheBusterBustingTestSixPath + "FileFour_v7.txt");
            CopyTestFile(CacheBusterBustingTestSixPath + "FileFour.txt", CacheBusterBustingTestSixPath + "FileFour_v5.txt");
            CopyTestFile(CacheBusterBustingTestSixPath + "FileFour.txt", CacheBusterBustingTestSixPath + "FileFour_v6.txt");

            CreateTestFile(CacheBusterBustingTestSixPath + "FileFive.txt");
            CopyTestFile(CacheBusterBustingTestSixPath + "FileFive.txt", CacheBusterBustingTestSixPath + "FileFive_v4.txt");
            CopyTestFile(CacheBusterBustingTestSixPath + "FileFive.txt", CacheBusterBustingTestSixPath + "FileFive_v5.txt");
            CopyTestFile(CacheBusterBustingTestSixPath + "FileFive.txt", CacheBusterBustingTestSixPath + "FileFive_v3.txt");
            CopyTestFile(CacheBusterBustingTestSixPath + "FileFive.txt", CacheBusterBustingTestSixPath + "FileFive_v2.txt");

            List<FileInfo> files = new DirectoryInfo(CacheBusterBustingTestSixPath).GetFiles("*.*", SearchOption.AllDirectories).ToList();
            Assert.AreEqual(15, files.Count);


            string[] arguments = new[]
                                     {
                                         "-afp:" + CacheBusterBustingTestSixPath,
                                         "-c:2",
                                         "-k:2",
                                         "-m:1"
                                     };

            CacheBuster.ProcessCommandLineArguments(arguments);
            CacheBuster.Go();

            // assert that relevant files exist and have been deleted etc
            files = new DirectoryInfo(CacheBusterBustingTestSixPath).GetFiles("*.*", SearchOption.AllDirectories).ToList();

            Assert.AreEqual(9, files.Count);

            // assert all nine files exist
            Assert.IsTrue(files.Any(c => c.Name == "FileOne.txt"));
            Assert.IsTrue(files.Any(c => c.Name == "FileTwo.txt"));
            Assert.IsTrue(files.Any(c => c.Name == "FileTwo_v1.txt"));
            Assert.IsTrue(files.Any(c => c.Name == "FileThree_v3.txt"));
            Assert.IsTrue(files.Any(c => c.Name == "FileThree_v4.txt"));
            Assert.IsTrue(files.Any(c => c.Name == "FileFour_v6.txt"));
            Assert.IsTrue(files.Any(c => c.Name == "FileFour_v7.txt"));
            Assert.IsTrue(files.Any(c => c.Name == "FileFive_v4.txt"));
            Assert.IsTrue(files.Any(c => c.Name == "FileFive_v5.txt"));
        }

        [Test]
        public void WhenCleaningUpAssetsUsingHashesOldVersionsShouldBeCleanedUpCorrectlyButOriginalVersionsShouldBeKept()
        {
            CreateTestFile(CacheBusterBustingTestSixPath + "FileOne.txt");

            CreateTestFile(CacheBusterBustingTestSixPath + "FileTwo.txt");
            CopyTestFile(CacheBusterBustingTestSixPath + "FileTwo.txt", CacheBusterBustingTestSixPath + "FileTwo__asdfweruioyweroi38u3.txt");

            CreateTestFile(CacheBusterBustingTestSixPath + "FileThree.txt");
            CopyTestFile(CacheBusterBustingTestSixPath + "FileThree.txt", CacheBusterBustingTestSixPath + "FileThree__asdfweruioyweroi38u3.txt");
            CopyTestFile(CacheBusterBustingTestSixPath + "FileThree.txt", CacheBusterBustingTestSixPath + "FileThree__wer45srfgas34r324awe.txt");
            File.Delete(CacheBusterBustingTestSixPath + "FileThree.txt");
            CreateTestFile(CacheBusterBustingTestSixPath + "FileFour.txt");
            CopyTestFile(CacheBusterBustingTestSixPath + "FileFour.txt", CacheBusterBustingTestSixPath + "FileFour__asdfweruioyweroi38u3.txt");
            CopyTestFile(CacheBusterBustingTestSixPath + "FileFour.txt", CacheBusterBustingTestSixPath + "FileFour__wer45srfgas34r324awe.txt");
            CopyTestFile(CacheBusterBustingTestSixPath + "FileFour.txt", CacheBusterBustingTestSixPath + "FileFour__2309ujowseolijlqiejr.txt");

            CreateTestFile(CacheBusterBustingTestSixPath + "FileFive.txt");
            CopyTestFile(CacheBusterBustingTestSixPath + "FileFive.txt", CacheBusterBustingTestSixPath + "FileFive__asdfweruioyweroi38u3.txt");
            CopyTestFile(CacheBusterBustingTestSixPath + "FileFive.txt", CacheBusterBustingTestSixPath + "FileFive__wer45srfgas34r324awe.txt");
            CopyTestFile(CacheBusterBustingTestSixPath + "FileFive.txt", CacheBusterBustingTestSixPath + "FileFive__2309ujowseolijlqiejr.txt");
            CopyTestFile(CacheBusterBustingTestSixPath + "FileFive.txt", CacheBusterBustingTestSixPath + "FileFive__sfdewfsdf098903sdfsd.txt");

            List<FileInfo> files = new DirectoryInfo(CacheBusterBustingTestSixPath).GetFiles("*.*", SearchOption.AllDirectories).ToList();
            Assert.AreEqual(14, files.Count);

            string[] arguments = new[]
                                     {
                                         "-afp:" + CacheBusterBustingTestSixPath,
                                         "-c:3",
                                         "-hp:__",
                                         "-k:2"
                                     };

            CacheBuster.ProcessCommandLineArguments(arguments);
            CacheBuster.Go();

            // assert that relevant files exist and have been deleted etc
            files = new DirectoryInfo(CacheBusterBustingTestSixPath).GetFiles("*.*", SearchOption.AllDirectories).ToList();

            Assert.AreEqual(11, files.Count);

            // assert all nine files exist
            Assert.IsTrue(files.Any(c => c.Name == "FileOne.txt"));
            Assert.IsTrue(files.Any(c => c.Name == "FileTwo.txt"));
            Assert.IsTrue(files.Any(c => c.Name == "FileTwo__asdfweruioyweroi38u3.txt"));
            Assert.IsTrue(files.Any(c => c.Name == "FileThree__asdfweruioyweroi38u3.txt"));
            Assert.IsTrue(files.Any(c => c.Name == "FileThree__wer45srfgas34r324awe.txt"));
            Assert.IsTrue(files.Any(c => c.Name == "FileFour.txt"));
            Assert.IsTrue(files.Any(c => c.Name == "FileFour__wer45srfgas34r324awe.txt"));
            Assert.IsTrue(files.Any(c => c.Name == "FileFour__2309ujowseolijlqiejr.txt"));
            Assert.IsTrue(files.Any(c => c.Name == "FileFive.txt"));
            Assert.IsTrue(files.Any(c => c.Name == "FileFive__2309ujowseolijlqiejr.txt"));
            Assert.IsTrue(files.Any(c => c.Name == "FileFive__sfdewfsdf098903sdfsd.txt"));
        }

        [Test]
        public void WhenCleaningUpAssetsUsingVersionNumbersOldVersionsShouldBeCleanedUpCorrectlyButOriginalVersionsShouldBeKept()
        {
            CreateTestFile(CacheBusterBustingTestSixPath + "FileOne.txt");

            CreateTestFile(CacheBusterBustingTestSixPath + "FileTwo.txt");
            CopyTestFile(CacheBusterBustingTestSixPath + "FileTwo.txt", CacheBusterBustingTestSixPath + "FileTwo_v1.txt");

            CreateTestFile(CacheBusterBustingTestSixPath + "FileThree.txt");
            CopyTestFile(CacheBusterBustingTestSixPath + "FileThree.txt", CacheBusterBustingTestSixPath + "FileThree_v4.txt");
            CopyTestFile(CacheBusterBustingTestSixPath + "FileThree.txt", CacheBusterBustingTestSixPath + "FileThree_v3.txt");
            File.Delete(CacheBusterBustingTestSixPath + "FileThree.txt");

            CreateTestFile(CacheBusterBustingTestSixPath + "FileFour.txt");
            CopyTestFile(CacheBusterBustingTestSixPath + "FileFour.txt", CacheBusterBustingTestSixPath + "FileFour_v7.txt");
            CopyTestFile(CacheBusterBustingTestSixPath + "FileFour.txt", CacheBusterBustingTestSixPath + "FileFour_v5.txt");
            CopyTestFile(CacheBusterBustingTestSixPath + "FileFour.txt", CacheBusterBustingTestSixPath + "FileFour_v6.txt");

            CreateTestFile(CacheBusterBustingTestSixPath + "FileFive.txt");
            CopyTestFile(CacheBusterBustingTestSixPath + "FileFive.txt", CacheBusterBustingTestSixPath + "FileFive_v4.txt");
            CopyTestFile(CacheBusterBustingTestSixPath + "FileFive.txt", CacheBusterBustingTestSixPath + "FileFive_v5.txt");
            CopyTestFile(CacheBusterBustingTestSixPath + "FileFive.txt", CacheBusterBustingTestSixPath + "FileFive_v3.txt");
            CopyTestFile(CacheBusterBustingTestSixPath + "FileFive.txt", CacheBusterBustingTestSixPath + "FileFive_v2.txt");

            List<FileInfo> files = new DirectoryInfo(CacheBusterBustingTestSixPath).GetFiles("*.*", SearchOption.AllDirectories).ToList();
            Assert.AreEqual(14, files.Count);


            string[] arguments = new[]
                                     {
                                         "-afp:" + CacheBusterBustingTestSixPath,
                                         "-c:3",
                                         "-k:2",
                                         "-m:1"
                                     };

            CacheBuster.ProcessCommandLineArguments(arguments);
            CacheBuster.Go();

            // assert that relevant files exist and have been deleted etc
            files = new DirectoryInfo(CacheBusterBustingTestSixPath).GetFiles("*.*", SearchOption.AllDirectories).ToList();

            Assert.AreEqual(11, files.Count);

            // assert all nine files exist
            Assert.IsTrue(files.Any(c => c.Name == "FileOne.txt"));
            Assert.IsTrue(files.Any(c => c.Name == "FileTwo.txt"));
            Assert.IsTrue(files.Any(c => c.Name == "FileTwo_v1.txt"));
            Assert.IsTrue(files.Any(c => c.Name == "FileThree_v3.txt"));
            Assert.IsTrue(files.Any(c => c.Name == "FileThree_v4.txt"));
            Assert.IsTrue(files.Any(c => c.Name == "FileFour.txt"));
            Assert.IsTrue(files.Any(c => c.Name == "FileFour_v6.txt"));
            Assert.IsTrue(files.Any(c => c.Name == "FileFour_v7.txt"));
            Assert.IsTrue(files.Any(c => c.Name == "FileFive.txt"));
            Assert.IsTrue(files.Any(c => c.Name == "FileFive_v4.txt"));
            Assert.IsTrue(files.Any(c => c.Name == "FileFive_v5.txt"));
        }

        #endregion Clean up tests

        #region Test helper methods

        private List<string> GetAssetExtensions(string output)
        {
            List<string> assetsExtensions = new List<string>();
            List<string> sourceExtensions = new List<string>();
            GetAssetAndSourceExtensions(output, ref assetsExtensions, ref sourceExtensions);
            return assetsExtensions;
        }

        private List<string> GetSourceExtensions(string output)
        {
            List<string> assetsExtensions = new List<string>();
            List<string> sourceExtensions = new List<string>();
            GetAssetAndSourceExtensions(output, ref assetsExtensions, ref sourceExtensions);
            return sourceExtensions;
        }

        private void GetAssetAndSourceExtensions(string output, ref List<string> assetsExtensions, ref List<string> sourceExtensions)
        {
            const string toSearchFor = "Source folders unique extensions:";
            string assetsString = output.Substring(0, output.IndexOf(toSearchFor));
            assetsString = assetsString.Substring(assetsString.IndexOf(":") + 1);
            string sourceString = output.Substring(output.IndexOf(toSearchFor) + toSearchFor.Length);

            assetsExtensions = assetsString.Split('\r', '\n').Where(c => !string.IsNullOrWhiteSpace(c)).ToList();
            sourceExtensions = sourceString.Split('\r', '\n').Where(c => !string.IsNullOrWhiteSpace(c)).ToList();
        }

        #endregion Test helper methods

    }
}
